
#include "cppuhelper/bootstrap.hxx"
#include <QApplication>
#include <QDebug>
#include <QVBoxLayout>
#include <QWidget>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <iostream>
#include <rtl/ustring.hxx>

using namespace com::sun::star;
using namespace rtl;

void getDispatchProvider(uno::Reference<frame::XModel> const& model)
{
    com::sun::star::uno::Reference<com::sun::star::frame::XController>
        controller = model->getCurrentController(); // 获取文档的控制器

    if (controller.is()) {
        com::sun::star::uno::Reference<com::sun::star::frame::XFrame> frame = controller->getFrame(); // 获取控制器的框架

        if (frame.is()) {
            uno::Reference<awt::XWindow> calcWindow = frame->getContainerWindow();
            if (calcWindow.is()) {
                qDebug() << "calcWindow is ok";
                // calcWindow->setVisible(false);
            }
            com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider>
                dispatchProvider(frame, uno::UNO_QUERY);

            if (dispatchProvider.is()) {
                // 现在您可以使用 dispatchProvider 来执行命令
                qDebug() << "get dispatchProvider";
                // 获取 DispatchHelper 来执行命令
                util::URL aurl;
                aurl.Complete = OUString::createFromAscii(".uno:MenuBar");
                uno::Reference<frame::XDispatch> xDispatch = dispatchProvider->queryDispatch(
                    aurl, // URL of the command
                    OUString::createFromAscii("" /*Frame name*/), 0 /*Search flags*/);

                // 检查 Dispatch 是否有效
                if (xDispatch.is()) {
                    // 执行命令，不带任何参数
                    uno::Sequence<beans::PropertyValue> aArgs(0);
                    xDispatch->dispatch(aurl, aArgs);
                } else {
                    qDebug() << "no such dispatch: menubar";
                }
            }
        }
    }
}

void ToggleMenuBar(uno::Reference<uno::XComponentContext> const& xContext)
{
    // 获取当前窗口的 DispatchProvider
    uno::Reference<frame::XDispatchProvider> dispatchProvider(
        xContext->getServiceManager()->createInstanceWithContext(
            OUString::createFromAscii("com.sun.star.frame.XDispatchProvider"),
            xContext),
        uno::UNO_QUERY);

    if (!dispatchProvider.is()) {
        std::cerr << "dispatchProvider is null" << std::endl;
        return;
    }
    // 获取 DispatchHelper 来执行命令
    util::URL aurl;
    aurl.Complete = OUString::createFromAscii(".uno:MenuBar");
    uno::Reference<frame::XDispatch> xDispatch = dispatchProvider->queryDispatch(
        aurl, // URL of the command
        OUString::createFromAscii("" /*Frame name*/), 0 /*Search flags*/);

    // 检查 Dispatch 是否有效
    if (xDispatch.is()) {
        // 执行命令，不带任何参数
        uno::Sequence<beans::PropertyValue> aArgs(0);
        xDispatch->dispatch(aurl, aArgs);
    }
}

class LibreOfficeEmbed : public QWidget {
    Q_OBJECT
public:
    LibreOfficeEmbed(QWidget* parent = nullptr)
        : QWidget(parent)
    {
        try {
            // 初始化LibreOffice的UNO环境
            com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>
                localContext = cppu::bootstrap();

            // 获取服务管理器
            com::sun::star::uno::Reference<
                com::sun::star::lang::XMultiComponentFactory>
                serviceManager(localContext->getServiceManager());

            // 加载LibreOffice Calc组件
            com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader>
                desktop(
                    serviceManager->createInstanceWithContext(
                        rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"),
                        localContext),
                    com::sun::star::uno::UNO_QUERY);

            com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>
                loadProps;
            loadProps.realloc(1);
            loadProps[0].Name = rtl::OUString::createFromAscii("Hidden");
            loadProps[0].Value <<= sal_Bool(false); // 尝试不隐藏窗口

            com::sun::star::uno::Reference<com::sun::star::uno::XInterface> document(
                desktop->loadComponentFromURL(
                    rtl::OUString::createFromAscii("file:///home/like/tmp/1.xlsx"),
                    "_blank", 0, loadProps));

            if (document.is()) {
                uno::Reference<frame::XModel> model(document, uno::UNO_QUERY);
                if (!model.is()) {
                    std::cerr << "can not get Model" << std::endl;
                } else {
                    std::cout << "is a Model" << std::endl;
                    getDispatchProvider(model);
                }

                css::uno::Reference<css::sheet::XSpreadsheetDocument> sheet_document(document, css::uno::UNO_QUERY);
                if (sheet_document.is()) {
                    qDebug() << "is sheet_document";
                }
                // ToggleMenuBar(localContext);

            } else {
                std::cerr << "Failed to load Calc document." << std::endl;
            }
        } catch (const com::sun::star::uno::Exception& e) {
            std::cerr << "Exception: "
                      << rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US)
                             .getStr()
                      << std::endl;
        }
    }
};

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    LibreOfficeEmbed widget;
    // widget.show();

    return app.exec();
}

#include "moc_main.cpp"
